using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using RoardersAgentSim.Map;
using System.Configuration;
using System.IO;

namespace RoardersAgentSim.Agent
{
    public class ShelterManager
    {
        /// <summary>
        /// list of shelters
        /// </summary>
        public List<Shelter> Shelters
        {
            get;
            private set;
        }
        #region public methods
        /// <summary>
        /// Determine if the residual capacity is 0 for all items
        /// </summary>
        /// <returns></returns>
        public bool zr_IsEmpty()
        {
            bool empty = false;
            if (Shelters.TrueForAll(x => x.zr == 0))
                empty = true;
            return empty;
        }

        /// <summary>
        /// Initialisation
        /// </summary>
        internal void Initialize(Map.FullMap map)
        {
            LogHelper.LogStep("Shelters initialised");
            this.Shelters = new List<Shelter>();
            int id = 1;
            foreach (Node n in map.Nodes.Where(x => x.HasShelter))
            {
                Shelter sh = new Shelter();
                sh.Node = n;
                sh.ShelterID = id++;
                switch (n.NodeType)
                {
                    case NodeType.HOSPITAL_NODE:
                        sh.psi = 1;
                        sh.ShelterType = ShelterType.HOSPITAL;
                        break;
                    case NodeType.SHELTER_NODE:
                        sh.psi = 0;
                        sh.ShelterType = ShelterType.SHELTER;
                        break;
                }
                sh.z = n.ShelterCapacity;
                sh.zr = n.ShelterCapacity;
                Shelters.Add(sh);
            }
        }
        /// <summary>
        /// Update the residual capacity with the same number for all
        /// shelter
        /// </summary>
        /// <param name="new_people"></param>
        public void UpdateResidualCapacity(int new_people) // A4.1
        {
            LogHelper.LogStep("UpdateResidualCapacity - A4.1");
            foreach (Shelter sh in Shelters)
                sh.UpdateResidualCapacity(new_people);
        }
        #endregion


        /// <summary>
        /// Save the shelter state in a txt file
        /// </summary>
        /// <param name="time"></param>
        internal void SaveState(int time)
        {
            string directory = ConfigurationManager.AppSettings["output"];
            if (!directory.EndsWith(@"\"))
                directory += @"\";
            string fileName = string.Format("{0}_{1}.{2}", "SHELTER", DateTime.Now.ToString("yyyyMMddHHmm"), "txt");
            StreamWriter file = new StreamWriter(directory + fileName,true);
            file.WriteLine(String.Format("Simulation time = {0}", time));
            file.WriteLine("Nodes information");
            int i = 0;
            int len = this.Shelters.Count;
            foreach (Shelter sh in this.Shelters)
            {
                i++;
                file.WriteLine(String.Format("{0} {1}/{2}", sh.Description, i, len));
                file.WriteLine(string.Format("Type {0}", (sh.ShelterType == ShelterType.HOSPITAL ? "HOSPITAL" : "SHELTER")));
                file.WriteLine(string.Format("         Capacity {0}", sh.z));
                file.WriteLine(string.Format("Residual capacity {0}", sh.zr));
            }
            file.Close();
        }

        internal Dictionary<int, int> FlowInitialisation()
        {
            Dictionary<int, int> toReturn = new Dictionary<int, int>();
            foreach (Shelter sh in this.Shelters)
            {
                toReturn.Add(sh.ShelterID, 0);
            }
            return toReturn;
        }

        internal void ExportPerformance()
        {
            string directory = Utils.GetOutputDirectory();
            string filename = string.Format("{0}_{1}.{2}", Utils.FilePrefix, "shelter_full_time", "csv");
            StreamWriter file = new StreamWriter(directory + filename, true);
            file.WriteLine(GetPerformanceHeader());
            foreach (Shelter sh in this.Shelters)
            {
                file.WriteLine(sh.Node.NodeID+Utils.GetCSVDelimiter()+sh.FullTime);
            }
            file.Close();
        }

        private string GetPerformanceHeader()
        {
            string header = "Node_Shelter" + Utils.GetCSVDelimiter() + "Full_Time";
            return header;
        }
    }
}
